package model

import (
	"errors"
	"github.com/hwcer/cosgo/schema"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/updater/operator"
	"server/share/config"
	"strconv"
	"strings"
)

func init() {
	Register(&Shop{})
}

// ShopShelf 格子信息
type ShopShelf struct {
	Key    int32 `json:"k,omitempty" bson:"k"` //商品ID
	Value  int32 `json:"v,omitempty" bson:"v"` //已经购买的数据
	Expire int64 `json:"t,omitempty" bson:"t"` //过期时间，商店模式2，格子刷新有效
}

// ShopDiscount 已经获得的优惠信息
type ShopDiscount struct {
	Key   int32 `json:"k,omitempty" bson:"k"` //打折优惠表ID
	Value int32 `json:"v,omitempty" bson:"v"` //已经购买的数量s
	//Expire int64 `json:"t,omitempty" bson:"t"` //过期时间
}

func (dis *ShopDiscount) MayRefresh(key int32) {
	if dis.Key != key {
		dis.Key = key
		dis.Value = 0
	}
}

// Shop 商店信息
type Shop struct {
	Model    `bson:"inline"`
	Sales    int32                  `json:"sales,omitempty" bson:"sales"`       //累计购买次数,仅仅 刷新模式 1,2 有效
	Expire   int64                  `json:"expire,omitempty" bson:"expire"`     //过期时间，商店模式1，整体刷新有效
	Update   int64                  `json:"update,omitempty" bson:"update"`     //最后更新时间
	Shelves  map[int32]ShopShelf    `json:"shelves" bson:"shelves"`             //货架
	Discount map[int32]ShopDiscount `json:"discount,omitempty" bson:"discount"` //打折信息
}

func (this *Shop) Get(k string) (any, bool) {
	switch k {
	case "Shelves", "shelves":
		return this.Shelves, true
	case "Discount", "discount":
		return this.Discount, true
	case "Sales", "sales":
		return this.Sales, true
	case "Expire", "expire":
		return this.Expire, true
	case "Update", "update":
		return this.Update, true
	default:
		return this.Model.Get(k)
	}
}

// Set 更新器
func (this *Shop) Set(k string, v any) (any, bool) {
	if i := strings.Index(k, "."); i > 0 {
		return this.setMapValue(k[0:i], k[i+1:], v)
	}

	switch k {
	case "Shelves", "shelves":
		this.Shelves = v.(map[int32]ShopShelf)
	case "Discount", "discount":
		this.Discount = v.(map[int32]ShopDiscount)
	case "Sales", "sales":
		this.Sales = v.(int32)
	case "Expire", "expire":
		this.Expire = v.(int64)
	case "Update", "update":
		this.Update = v.(int64)
	default:
		return this.Model.Set(k, v)
	}
	return v, true
}
func (this *Shop) GetDiscount(id int32) ShopDiscount {
	if this.Discount == nil {
		return ShopDiscount{}
	}
	r, ok := this.Discount[id]
	if !ok {
		return ShopDiscount{}
	}
	return r
}

func (this *Shop) setMapValue(name, key string, v any) (any, bool) {
	iid, err := strconv.ParseInt(key, 10, 32)
	if err != nil {
		return v, false
	}
	var ok bool
	switch name {
	case "Shelves", "shelves":
		ok = true
		this.Shelves[int32(iid)] = v.(ShopShelf)
	case "Discount", "discount":
		ok = true
		this.Discount[int32(iid)] = v.(ShopDiscount)
	}
	return v, ok
}

func (this *Shop) Clone() *Shop {
	r := *this
	return &r
}

func (this *Shop) IType(int32) int32 {
	return config.ITypeShop
}

// ----------------- 作为MODEL方法--------------------
func (this *Shop) Schema() *schema.Schema {
	sch, _ := schema.Parse(this)
	return sch
}
func (this *Shop) Upsert(u *updater.Updater, op *operator.Operator) bool {
	return true
}

func (this *Shop) Getter(u *updater.Updater, coll *dataset.Collection, keys []string) error {
	uid := u.Uid()
	if uid == "" {
		return errors.New("Shop.Getter uid not found")
	}
	tx := db.Where("uid = ?", uid)
	if len(keys) > 0 {
		tx = tx.Where("_id IN ?", keys)
	}
	var rows []*Shop
	if tx = tx.Find(&rows); tx.Error != nil {
		return tx.Error
	}
	for _, v := range rows {
		coll.Receive(v.OID, v)
	}
	return nil
}

func (this *Shop) Setter(u *updater.Updater, bulkWrite dataset.BulkWrite) error {
	return bulkWrite.Submit()
}

func (this *Shop) BulkWrite(u *updater.Updater) dataset.BulkWrite {
	return NewBulkWrite(this)
}
